package com.ecarx.vhaltests.hy11.testcases.climate;

import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.AIR_FRAGRANCE_SLOT_1;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.AIR_FRAGRANCE_SLOT_2;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.AIR_FRAGRANCE_SLOT_3;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.HVAC_FUNC_AIR_FRAGRANCE_SLOT;
import static com.ecarx.xui.adaptapi.car.hvac.IFragrance.HVAC_FUNC_AUTO_REFRESHING_FRAGRANCE;
import static org.junit.Assert.assertEquals;

import android.car.VehicleAreaType;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;

import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacFuncAutoRefreshingFragranceTest extends VhalUnitTestBase {
    private static IWrapper.IPropertyId propertyId;
    private static IWrapper.IPropertyId setSlot;

    protected static IWrapper wrapper;
    private static IpcpClient ipcpClient = new IpcpClient();
    private static final int AREA_ID = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;

    private static boolean cbkPropValue;
    private static int cbkPropStatus;
    private static int SLOT_1;
    private static int SLOT_2;
    private static int SLOT_3;

    @BeforeClass
    public static void testInit() {
        wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        propertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, HVAC_FUNC_AUTO_REFRESHING_FRAGRANCE);
        setSlot = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, HVAC_FUNC_AIR_FRAGRANCE_SLOT);
        SLOT_1 = setSlot.getPropertyValue(AIR_FRAGRANCE_SLOT_1);
        SLOT_2 = setSlot.getPropertyValue(AIR_FRAGRANCE_SLOT_2);
        SLOT_3 = setSlot.getPropertyValue(AIR_FRAGRANCE_SLOT_3);
        setConfig();
    }

    public boolean availability(){
        return mCarPropertyMgr.isPropertyAvailable(propertyId.getPropertyId(), AREA_ID);
    }

    public static void setConfig(){
        int ccSvcId = 135;
        int[] ccOperIds = {200};
        boolean ccSet = ipcpClient.setConfig(ccSvcId, ccOperIds);
        assertEquals(true, ccSet);

        int cemSvcId = 37;
        int[] cemOperId = {999};
        boolean cemResult = ipcpClient.setConfig(cemSvcId, cemOperId);
        assertEquals(true, cemResult);
        delay();
    }

    public void setCarConfig(boolean isAvail){
        int ccSvcId = 135;
        int ccOperIds = 200;
        int[] configs = {500, 505};
        int[] values = {isAvail? 2:1, isAvail? 2:1};
        boolean ccResult = ipcpClient.setCarconfigSignal(ccSvcId, ccOperIds, configs, values);
        delay();
        assertEquals(true, ccResult);
        Log.d("vli", "setCarConfig pass");
    }

    public void setCem(boolean isActive){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1"};
        int[] cemValues = {isActive? VehicleConstants.USG_MODE_CONVENIENCE:VehicleConstants.USG_MODE_ABANDON,
                VehicleConstants.CAR_MODE_DYNO};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        delay();
        assertEquals(true, cemUsgResult);
        Log.d("vli", "setCem pass");
    }

    @Test
    public void test_001AutoRefreshingActive(){
        setCarConfig(true);
        setCem(true);
        mockTypeIdAndSlot(0, 0, 0, 0, 0, 1);
        selectSlot(3);
        mockTypeIdAndSlot(0, 0, 226, 0, 0, 1);
        delay(2000);
        int propStatus = mCarPropertyMgr.getProperty(Boolean.class, propertyId.getPropertyId(), AREA_ID).getStatus();
        assertEquals(0, propStatus);
    }

    @Test
    public void test_002AutoRefreshingNotActive(){
        setCarConfig(true);
        setCem(false);
        mockTypeIdAndSlot(0, 228, 0, 0, 1, 0);
        delay();
        int propStatus = mCarPropertyMgr.getProperty(Boolean.class, propertyId.getPropertyId(), AREA_ID).getStatus();
        assertEquals(1, propStatus);
    }

    @Test
    public void test_003AutoRefreshingNotAvail(){
        setCarConfig(false);
        delay();
        assertEquals(false, availability());
    }

    @Test
    public void test_004SetAUtoRefreshingTrue(){
        setCarConfig(true);
        setCem(true);
        mockTypeIdAndSlot(0,0,0, 0,0,1);
        selectSlot(SLOT_3);
        mockTypeIdAndSlot(0,0,227, 0,0,1);
        mCarPropertyMgr.setBooleanProperty(propertyId.getPropertyId(), AREA_ID,true);
        delay();
        boolean propValue = mCarPropertyMgr.getBooleanProperty(propertyId.getPropertyId(), AREA_ID);
        assertEquals(true, propValue);
    }

    @Test
    public void test_005SetAutoRefreshingFalse(){
        setCarConfig(true);
        setCem(false);
        mockTypeIdAndSlot(0,0,0,0,1,0);
        delay(3000);
        selectSlot(SLOT_2);
        mockTypeIdAndSlot(0,226,0,0,1,0);
        delay(3000);
        mCarPropertyMgr.setBooleanProperty(propertyId.getPropertyId(), AREA_ID,false);
        delay();
        boolean propValue = mCarPropertyMgr.getBooleanProperty(propertyId.getPropertyId(), AREA_ID);
        assertEquals(false, propValue);
    }

    @Test
    public void test_006AutoRefreshingCallback(){
        CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
            @Override
            public void onChangeEvent(CarPropertyValue carPropertyValue) {
                cbkPropValue = (boolean)carPropertyValue.getValue();
                cbkPropStatus = carPropertyValue.getStatus();
            }

            @Override
            public void onErrorEvent(int i, int i1) {

            }
        };

        mCarPropertyMgr.registerCallback(carPropertyEventCallback, propertyId.getPropertyId(), CarPropertyManager.SENSOR_RATE_ONCHANGE);
        CarPropertyValue<Boolean> carProp = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID);
        int oldPropStatus = carProp.getStatus();
        if(oldPropStatus == 0){
            //set notAvail
            setCarConfig(false);
            assertEquals(false, availability());
        }else{
            //set Active
            setCarConfig(true);
            setCem(false);
            mockTypeIdAndSlot(0,0,0,0,1,0);
            delay(1000);
            selectSlot(SLOT_2);
            mockTypeIdAndSlot(0,226,0,0,1,0);
            delay(1000);
            assertEquals(0, cbkPropStatus);
            mCarPropertyMgr.setBooleanProperty(propertyId.getPropertyId(), AREA_ID, true);
            delay();
            boolean res = mCarPropertyMgr.getBooleanProperty(propertyId.getPropertyId(), AREA_ID);
            assertEquals(true, res);
        }
        mCarPropertyMgr.unregisterCallback(carPropertyEventCallback);
    }

    public void mockTypeIdAndSlot(int Id1, int Id2, int Id3, int ch1, int ch2, int ch3){
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts","vehModMngtGlbSafe1CarModSts1","fragCh1Id", "fragCh2Id", "fragCh3Id","airFragCh1RunngSts", "airFragCh2RunngSts", "airFragCh3RunngSts"};
        int[] cemValues = {VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_DYNO, Id1, Id2, Id3, ch1, ch2, ch3};
        boolean cemUsgResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        delay();
        assertEquals(true, cemUsgResult);
    }

    public void selectSlot(int slot){
        if(slot==1){
            mCarPropertyMgr.setIntProperty(setSlot.getPropertyId(), AREA_ID, SLOT_1);
        }else if(slot==2){
            mCarPropertyMgr.setIntProperty(setSlot.getPropertyId(), AREA_ID, SLOT_2);
        }else if(slot==3){
            mCarPropertyMgr.setIntProperty(setSlot.getPropertyId(), AREA_ID, SLOT_3);
        }
    }

    @Test
    public void test_007AutoRefreshingId(){
        setCarConfig(true);
        setCem(false);
        //普通香型
        mockTypeIdAndSlot(225, 0, 0, 1, 0, 0);
        delay(3000);
        selectSlot(SLOT_1);
        int curSlot = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        int propSts = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus();
        boolean propVal = mCarPropertyMgr.getBooleanProperty(propertyId.getPropertyId(), AREA_ID);
        delay(3000);
        assertEquals(SLOT_1, curSlot);
        assertEquals(1, propSts);
        assertEquals(false, propVal);

        mockTypeIdAndSlot(226, 0, 0, 1, 0, 0);
        delay(3000);
        selectSlot(SLOT_1);
        curSlot = mCarPropertyMgr.getIntProperty(setSlot.getPropertyId(), AREA_ID);
        propSts = mCarPropertyMgr.getProperty(propertyId.getPropertyId(), AREA_ID).getStatus();
        assertEquals(SLOT_1, curSlot);
        assertEquals(0, propSts);
    }
}
